package com.farmer.auth.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.farmer.auth.mapper.UserMapper;
import com.farmer.auth.service.AuthService;
import com.farmer.common.dto.LoginDTO;
import com.farmer.common.dto.RegisterDTO;
import com.farmer.common.entity.User;
import com.farmer.common.result.Result;
import com.farmer.common.utils.JwtUtils;
import com.farmer.common.utils.PasswordEncoder;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;

/**
 * 认证服务实现类
 */
@Slf4j
@Service
public class AuthServiceImpl implements AuthService {

    @Autowired
    private UserMapper userMapper;

    @Autowired
    private RedisTemplate<String, Object> redisTemplate;

    private static final String USER_TOKEN_PREFIX = "user:token:";
    private static final String USER_INFO_PREFIX = "user:info:";

    @Override
    public Result<?> login(LoginDTO loginDTO) {
        try {
            // 参数验证
            if (!StringUtils.hasText(loginDTO.getUsername()) || !StringUtils.hasText(loginDTO.getPassword())) {
                return Result.error("用户名和密码不能为空");
            }

            // 查询用户
            QueryWrapper<User> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("username", loginDTO.getUsername())
                       .eq("status", 1); // 只查询启用状态的用户
            User user = userMapper.selectOne(queryWrapper);

            if (user == null) {
                return Result.error("用户不存在或已被禁用");
            }

            // 验证密码
            log.info("验证密码 - 输入密码: {}, 数据库密码: {}", loginDTO.getPassword(), user.getPassword());
            boolean matches = PasswordEncoder.matches(loginDTO.getPassword(), user.getPassword());
            log.info("密码验证结果: {}", matches);
            
            if (!matches) {
                return Result.error("用户名或密码错误");
            }

            // 生成Token
            String token = JwtUtils.generateToken(user.getId(), user.getUsername(), user.getRole());

            // 将Token存储到Redis（设置7天过期）
            redisTemplate.opsForValue().set(USER_TOKEN_PREFIX + user.getId(), token, 7, TimeUnit.DAYS);

            // 存储用户信息到Redis
            Map<String, Object> userInfo = new HashMap<>();
            userInfo.put("id", user.getId());
            userInfo.put("username", user.getUsername());
            userInfo.put("nickname", user.getNickname());
            userInfo.put("role", user.getRole());
            userInfo.put("avatar", user.getAvatar());
            redisTemplate.opsForValue().set(USER_INFO_PREFIX + user.getId(), userInfo, 7, TimeUnit.DAYS);

            // 返回登录结果
            Map<String, Object> result = new HashMap<>();
            result.put("token", token);
            result.put("userInfo", userInfo);

            log.info("用户登录成功：{}", loginDTO.getUsername());
            return Result.success("登录成功", result);

        } catch (Exception e) {
            log.error("用户登录失败：{}", e.getMessage(), e);
            return Result.error("登录失败，请稍后重试");
        }
    }

    @Override
    public Result<?> register(RegisterDTO registerDTO) {
        try {
            // 验证两次密码是否一致
            if (!registerDTO.getPassword().equals(registerDTO.getConfirmPassword())) {
                return Result.error("两次输入的密码不一致");
            }

            // 检查用户名是否已存在
            QueryWrapper<User> usernameQuery = new QueryWrapper<>();
            usernameQuery.eq("username", registerDTO.getUsername());
            if (userMapper.selectCount(usernameQuery) > 0) {
                return Result.error("用户名已存在");
            }

            // 检查手机号是否已存在
            QueryWrapper<User> phoneQuery = new QueryWrapper<>();
            phoneQuery.eq("phone", registerDTO.getPhone());
            if (userMapper.selectCount(phoneQuery) > 0) {
                return Result.error("手机号已被注册");
            }

            // 创建新用户
            User user = new User();
            BeanUtils.copyProperties(registerDTO, user);
            user.setPassword(PasswordEncoder.encode(registerDTO.getPassword()));
            user.setRole("USER"); // 默认为普通用户
            user.setStatus(1); // 默认启用状态

            // 保存用户
            int result = userMapper.insert(user);
            if (result > 0) {
                log.info("用户注册成功：{}", registerDTO.getUsername());
                return Result.success("注册成功");
            } else {
                return Result.error("注册失败，请稍后重试");
            }

        } catch (Exception e) {
            log.error("用户注册失败：{}", e.getMessage(), e);
            return Result.error("注册失败，请稍后重试");
        }
    }

    @Override
    public Result<?> refreshToken(String token) {
        try {
            if (!StringUtils.hasText(token)) {
                return Result.error("Token不能为空");
            }

            // 验证Token
            if (!JwtUtils.validateToken(token)) {
                return Result.error("Token无效或已过期");
            }

            // 生成新Token
            String newToken = JwtUtils.refreshToken(token);
            if (newToken == null) {
                return Result.error("Token刷新失败");
            }

            // 获取用户ID并更新Redis中的Token
            Long userId = JwtUtils.getUserIdFromToken(token);
            if (userId != null) {
                redisTemplate.opsForValue().set(USER_TOKEN_PREFIX + userId, newToken, 7, TimeUnit.DAYS);
            }

            Map<String, Object> result = new HashMap<>();
            result.put("token", newToken);

            return Result.success("Token刷新成功", result);

        } catch (Exception e) {
            log.error("Token刷新失败：{}", e.getMessage(), e);
            return Result.error("Token刷新失败");
        }
    }

    @Override
    public Result<?> logout(String token) {
        try {
            if (!StringUtils.hasText(token)) {
                return Result.error("Token不能为空");
            }

            // 获取用户ID
            Long userId = JwtUtils.getUserIdFromToken(token);
            if (userId != null) {
                // 删除Redis中的Token和用户信息
                redisTemplate.delete(USER_TOKEN_PREFIX + userId);
                redisTemplate.delete(USER_INFO_PREFIX + userId);
            }

            log.info("用户登出成功，userId：{}", userId);
            return Result.success("登出成功");

        } catch (Exception e) {
            log.error("用户登出失败：{}", e.getMessage(), e);
            return Result.error("登出失败");
        }
    }

    @Override
    public Result<?> validateToken(String token) {
        try {
            if (!StringUtils.hasText(token)) {
                return Result.error("Token不能为空");
            }

            // 验证Token
            if (!JwtUtils.validateToken(token)) {
                return Result.error("Token无效或已过期");
            }

            // 获取用户信息
            Long userId = JwtUtils.getUserIdFromToken(token);
            String username = JwtUtils.getUsernameFromToken(token);
            String role = JwtUtils.getRoleFromToken(token);

            // 检查Redis中是否存在该Token
            String redisToken = (String) redisTemplate.opsForValue().get(USER_TOKEN_PREFIX + userId);
            if (!token.equals(redisToken)) {
                return Result.error("Token已失效");
            }

            Map<String, Object> result = new HashMap<>();
            result.put("userId", userId);
            result.put("username", username);
            result.put("role", role);
            result.put("valid", true);

            return Result.success("Token验证成功", result);

        } catch (Exception e) {
            log.error("Token验证失败：{}", e.getMessage(), e);
            return Result.error("Token验证失败");
        }
    }

    @Override
    public Result<?> resetAdminPassword() {
        try {
            // 查找admin用户
            QueryWrapper<User> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("username", "admin");
            User admin = userMapper.selectOne(queryWrapper);
            
            if (admin == null) {
                return Result.error("管理员用户不存在");
            }

            // 重新加密密码123456
            String newPassword = PasswordEncoder.encode("123456");
            admin.setPassword(newPassword);
            
            // 更新数据库
            int result = userMapper.updateById(admin);
            if (result > 0) {
                log.info("管理员密码重置成功，新密码hash: {}", newPassword);
                return Result.success("管理员密码重置成功");
            } else {
                return Result.error("密码重置失败");
            }
            
        } catch (Exception e) {
            log.error("重置管理员密码失败：{}", e.getMessage(), e);
            return Result.error("重置密码失败");
        }
    }
} 